import ElevatorPackage.Elevator;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.*;


public class UserInterface implements ActionListener, Observer {
    JMenuBar menuBar;
    JMenu menu;
    JMenuItem menuItem;
    JLabel timeLabel;

    int numFloors;
    LinkedList<JPanel> ElevatorColourSymbols;
    JPanel elevatorControlPanel;
    TreeMap<Integer, JButton> elevatorControls;
    TreeMap<Integer, LinkedList<JButton>> floorCallControls;
    JPanel floorPanel;
    Elevator elevator;
    JFrame frame;
    JScrollPane scrollPane;
    JTextArea textArea;
    boolean startAtZero;

    public void go(Elevator elevator, int numFloors, boolean startAtZero) {
        this.numFloors = numFloors;
        this.startAtZero = startAtZero;

        frame = new JFrame();
        frame.setTitle("Elevator Simulation");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        menuBar = new JMenuBar();
        menu = new JMenu("File");
        menu.setMnemonic(KeyEvent.VK_F);
        menu.getAccessibleContext().setAccessibleDescription(
                "The file menu option");
        menuBar.add(menu);

        menuItem = new JMenuItem("New Simulation",
                KeyEvent.VK_N);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(
                KeyEvent.VK_N, ActionEvent.ALT_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription(
                "Set admin settings");
        menuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                AdminUI dialog = new AdminUI();
                dialog.pack();
                dialog.setVisible(true);
            }
        });
        menu.add(menuItem);
        menu.addSeparator();
        menuItem = new JMenuItem("Exit",
                KeyEvent.VK_E);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(
                KeyEvent.VK_X, ActionEvent.ALT_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription(
                "Exit Program");
        menuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        menu.add(menuItem);
        frame.setJMenuBar(menuBar);


        this.elevator = elevator;
        this.elevator.addObserver(this);

        Integer mod;
        if (this.startAtZero) {
            mod = 0;
        } else mod = 1;
        elevatorControlPanel = new JPanel(new GridLayout(this.numFloors, 1));
        elevatorControls = new TreeMap<Integer, JButton>();
        for (int i = this.numFloors - 1; i >= 0; i--) {
            JButton button = new JButton(Integer.toString(i + mod));
            button.setName("elevatorControl " + Integer.toString(i));
            button.addActionListener(this);
            elevatorControls.put(i, button);
            elevatorControlPanel.add(button);
        }

        floorPanel = new JPanel(new GridLayout(this.numFloors, 4));
        ElevatorColourSymbols = new LinkedList<JPanel>();
        floorCallControls = new TreeMap<Integer, LinkedList<JButton>>();

        for (int i = this.numFloors - 1; i >= 0; i--) {
            JButton labelButton = new JButton(Integer.toString(i + mod));
            labelButton.setName(Integer.toString(i));
            labelButton.setForeground(Color.blue);
            labelButton.setBorderPainted(false);
            labelButton.setContentAreaFilled(false);
            labelButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {

                    SetNameBox dialog = new SetNameBox((JButton) e.getSource(), StoreSingle.getInstance().u);
                    dialog.pack();
                    dialog.setVisible(true);
                }
            });
            floorPanel.add(labelButton);

            JPanel x = new JPanel();
            ElevatorColourSymbols.addFirst(x);
            floorPanel.add(x);

            LinkedList<JButton> jButtonLinkedList = new LinkedList<JButton>();
            JButton button;
            button = new JButton("UP");
            button.setName(Integer.toString(i) + ", 1");
            jButtonLinkedList.add(button);
            button.addActionListener(this);
            floorPanel.add(button);

            button = new JButton("DOWN");
            button.setName(Integer.toString(i) + ", -1");
            jButtonLinkedList.add(button);
            button.addActionListener(this);
            floorPanel.add(button);
            floorCallControls.put(i, jButtonLinkedList);
        }

        JPanel x = ElevatorColourSymbols.get(elevator.getLocation());
        x.setBackground(Color.red);

        frame.add(BorderLayout.EAST, floorPanel);
        frame.add(BorderLayout.WEST, elevatorControlPanel);
        textArea = new JTextArea(8, 35);
        scrollPane = new

                JScrollPane(textArea);

        scrollPane.createVerticalScrollBar();
        frame.add(BorderLayout.SOUTH, scrollPane);
        timeLabel = new JLabel("Move time: " + elevator.getStepTime() + " Exchange Time: " + elevator.getExchangeTime()+ " (Milliseconds)");
        frame.add(BorderLayout.NORTH, timeLabel);
        frame.pack();
        frame.setVisible(true);

        for (
                JPanel panel
                : ElevatorColourSymbols)

        {
            panel.setBackground(Color.white);
        }

        ElevatorColourSymbols.get(elevator.getLocation()).

                setBackground(Color.red);

    }

    public void actionPerformed(ActionEvent e) {
        JButton button = (JButton) e.getSource();
        if (button.getName().contains("elevatorControl")) {
            elevator.addDisembarkLocation(Integer.parseInt(button.getName().replace("elevatorControl ", "")));
        } else {
            String[] x = button.getName().split(", ", 2);
            elevator.activateCall(Integer.parseInt(x[0]), Integer.parseInt(x[1]));
        }
        button.setForeground(Color.green);
    }

    public void update(Observable o, Object arg) {
        textArea.append("\n" + new Date().toString() + ": ");
        if (arg == Elevator.ElevatorAction.GET_DESTINATION)
            textArea.append("Getting Destination: " + (elevator.getDestination() + (!startAtZero ? 1 : 0)));
        else if (arg == Elevator.ElevatorAction.WAITING)
            textArea.append("Waiting");
        else if (arg == Elevator.ElevatorAction.MOVE)
            textArea.append("Moving: From " + ((elevator.getLocation() + (!startAtZero ? 1 : 0))) + " To " + ((elevator.getLocation() + 1) + (!startAtZero ? 1 : 0)));
        else if (arg == Elevator.ElevatorAction.ARRIVE_AT_FLOOR)
            textArea.append("Arrived at Floor: " + elevator.getLocation());
        else if (arg == Elevator.ElevatorAction.ARRIVE_AT_DESTINATION)
            textArea.append("Arrived at Destination: " + (elevator.getLocation() + (!startAtZero ? 1 : 0)));
        else if (arg == Elevator.ElevatorAction.STOP)
            textArea.append("Stopping");
        else if (arg == Elevator.ElevatorAction.OPEN_DOOR)
            textArea.append("Opening Door");
        else if (arg == Elevator.ElevatorAction.CLOSE_DOOR)
            textArea.append("Closing Door");
        else if (arg == Elevator.ElevatorAction.DISEMBARK_PASSENGERS)
            textArea.append("Disembarking Passengers");
        else if (arg == Elevator.ElevatorAction.DEPART_FLOOR)
            textArea.append("Disembarking Floor");

        textArea.setCaretPosition(textArea.getDocument().getLength());

        if (arg == Elevator.ElevatorAction.OPEN_DOOR) {
            JPanel x = ElevatorColourSymbols.get(((Elevator) o).getLocation());
            x.setBackground(Color.green);
        } else if (arg == Elevator.ElevatorAction.CLOSE_DOOR) {
            JPanel x = ElevatorColourSymbols.get(((Elevator) o).getLocation());
            x.setBackground(Color.red);
        } else if (arg == Elevator.ElevatorAction.ARRIVE_AT_FLOOR) {
            int loc = ((Elevator) o).getLocation();

            JPanel x = ElevatorColourSymbols.get(((Elevator) o).getPrevLocation());
            x.setBackground(Color.white);
            x = ElevatorColourSymbols.get(loc);
            x.setBackground(Color.red);
            // reset elevator controls and call buttons
            elevatorControls.get(loc).setForeground(Color.black);
            floorCallControls.get(loc).get(0).setForeground(Color.black);
            floorCallControls.get(loc).get(1).setForeground(Color.black);
        }
    }

    public void close() {
        frame.dispose();
    }
}
